{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 流程控制"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在相对深入了解了值的基本操作之后，我们需要再返回来对流程控制做更深入的了解。\n",
    "\n",
    "之前我们看过这个寻找质数的程序：\n",
    "\n",
    "```python\n",
    "for n in range(2, 100):\n",
    "    if n == 2:\n",
    "        print(n)\n",
    "        continue\n",
    "    for i in range(2, n):\n",
    "        if (n % i) == 0:\n",
    "            break\n",
    "    else:\n",
    "        print(n)  \n",
    "```\n",
    "\n",
    "这其中，包含了*分支*与*循环* —— 无论多复杂的流程控制用这两个东西就够了，就好像无论多复杂的电路最终都是由通路和开路仅仅两个状态构成的一样。\n",
    "\n",
    "> 今天的人们觉得这是 “天经地义” 的事情，可实际上并非如此。这是 1966 年的一篇论文所带来的巨大改变 —— *Flow diagrams, turing machines and languages with only two formation rules* by Böhm and Jacopini (1966)。实际上，直到上个世纪末，`GOTO` 语句才从各种语言里近乎 “灭绝”……\n",
    ">\n",
    "> 任何进步，无论大小，其实都相当不容易，都非常耗时费力 —— 在哪儿都一样。有兴趣、有时间，可以去浏览 Wikipedia 上的简要说明 —— [Wikipedia: Minimal structured control flow](https://en.wikipedia.org/wiki/Control_flow#Goto)。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## if 语句"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`if` 语句的最简单构成是这样 —— 注意第 1 行末尾的冒号 `:` 和第 2 行的缩进：\n",
    "\n",
    "```python\n",
    "if expression:\n",
    "    statements\n",
    "```\n",
    "\n",
    "如果表达式 `expression` 返回值为真，执行 `if` 语句块内部的 `statements`，否则，什么都不做，执行 `if` 之后的下一个语句。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "372 is even.\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "r = random.randrange(1, 1000)\n",
    "\n",
    "if r % 2 == 0:\n",
    "    print(f'{r} is even.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果，表达式 `expression` 返回值无论真假，我们都需要做一点相应的事情，那么我们这么写：\n",
    "\n",
    "```python\n",
    "if expression:\n",
    "    statements_for_True\n",
    "else:\n",
    "    statements_for_False\n",
    "```\n",
    "\n",
    "如果表达式 `expression` 返回值为真，执行 `if` 语句块内部的 `statements_for_True`，否则，就执行 `else` 语句块内部的 `statements_for_False`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "945 is odd.\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "r = random.randrange(1, 1000)\n",
    "\n",
    "if r % 2 == 0:\n",
    "    print(f'{r} is even.')\n",
    "else:\n",
    "    print(f'{r} is odd.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有时，表达式 `<expression>` 返回的值有多种情况，并且针对不同的情况我们都要做相应的事情，那么可以这么写：\n",
    "\n",
    "```python\n",
    "if expression_1:\n",
    "    statements_for_expression_1_True\n",
    "    \n",
    "elif expression_2:\n",
    "    statements_for_expression_2_True\n",
    "\n",
    "elif expression_3:\n",
    "    statements_for_expression_3_True\n",
    "\n",
    "elif expression_...:\n",
    "    statements_for_expression_..._True\n",
    "```\n",
    "\n",
    "Python 用 `elif` 处理这种多情况分支，相当于其它编程语言中使用 `switch` 或者 `case`……\n",
    "\n",
    "`elif` 是 `else if` 的缩写，作用相同。\n",
    "\n",
    "以下程序模拟投两个骰子的结果 —— 两个骰子数字加起来，等于 `7` 算平，大于 `7` 算大，小于 `7` 算小："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Big!\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "r = random.randrange(2, 13)\n",
    "\n",
    "if r == 7:\n",
    "    print('Draw!')\n",
    "elif r < 7:\n",
    "    print('Small!')\n",
    "elif r > 7:\n",
    "    print('Big!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当然你还可以模拟投飞了的情况，即，最终的骰子数是 `0` 或者 `1`，即，`< 2`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Small!\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "r = random.randrange(0, 13) # 生成的随机数应该从 0 开始了；\n",
    "\n",
    "if r == 7:\n",
    "    print('Draw!')\n",
    "elif r >= 2 and r < 7:      # 如果这里直接写 elif r < 7:，那么，else: 那一部分永远不会被执行……\n",
    "    print('Small!')\n",
    "elif r > 7:\n",
    "    print('Big!')\n",
    "else:\n",
    "    print('Not valid!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "toc-hr-collapsed": false
   },
   "source": [
    "## for 循环"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python 语言中，`for` 循环不使用其它语言中那样的计数器，取而代之的是 `range()` 这个我称其为 “整数等差数列生成器” 的函数。\n",
    "\n",
    "用 C 语言写循环是这样的：\n",
    "\n",
    "```C\n",
    "for( a = 0; a < 10; a = a + 1 ){\n",
    "    printf(\"value of a: %d\\n\", a);\n",
    "}\n",
    "```\n",
    "\n",
    "用 Python 写同样的东西，是这样的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "value of a: 0\n",
      "value of a: 1\n",
      "value of a: 2\n",
      "value of a: 3\n",
      "value of a: 4\n",
      "value of a: 5\n",
      "value of a: 6\n",
      "value of a: 7\n",
      "value of a: 8\n",
      "value of a: 9\n"
     ]
    }
   ],
   "source": [
    "for a in range(10):\n",
    "    print(f'value of a: {a}') #每次 a 的值都不同，从 0 递增至 9"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### range() 函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`range()` 是个内建函数，[它的文档](https://docs.python.org/3/library/functions.html#func-range)是这样写的：\n",
    "\n",
    "> **range**(_stop_) \n",
    ">\n",
    "> **range**(_start, stop[, step]_)\n",
    "\n",
    "只有一个参数的时候，这个参数被理解为 `stop`，生成一个从 `0` 开始，到 `stop - 1` 的整数数列。\n",
    "\n",
    "这就解释了为什么有的时候我们会在 `for ... in range(...):` 这种循环内的语句块里进行计算的时候，经常会在变量之后写上 `+ 1`，因为我们 range(n) 的返回数列中不包含 `n`，但我们有时候却需要 `n`。[点击这里返回看看第一章里提到的例子：所谓算法那一小节](Part.1.E.1.entrance.ipynb#plusone)。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "range(0, 10)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "InteractiveShell.ast_node_interactivity = \"all\"\n",
    "\n",
    "range(10)\n",
    "list(range(10)) # 将 range(10) 转换成 list，以便清楚看到其内容。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`start` 参数的默认值是 `0`。如需指定起点，那么得给 `range()` 传递两个参数，比如，`range(2, 13)`……"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(2, 13))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "第三个参数可选；`step`，步长，就相当于是 “等差数列” 当中的 “差”，默认值是 `1`。例如，`range(1, 10, 2)` 生成的是这样一个数列 `[1, 3, 5, 7, 9]`。所以，打印 `0 ～ 10` 之间的所有奇数，可以这样写："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "3\n",
      "5\n",
      "7\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "for i in range(1, 10, 2):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们也可以生成负数的数列："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(0, -10, -1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Continue、Break 和 Pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在循环的过程中，还可以用 `continue` 和 `break` 控制流程走向，通常是在某条件判断发生的情况下 —— 正如你早就见过的那样：\n",
    "\n",
    "```python\n",
    "for n in range(2, 100):\n",
    "    if n == 2:\n",
    "        print(n)\n",
    "        continue\n",
    "    for i in range(2, n):\n",
    "        if (n % i) == 0:\n",
    "            break\n",
    "    else:\n",
    "        print(n)  \n",
    "```\n",
    "\n",
    "`continue` 语句将忽略其后的语句开始下次循环，而 `break` 语句将从此结束当前循环，开始执行循环之后的语句：\n",
    "\n",
    "![](images/continue-break.png)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`for` 语句块还可以附加一个 `else` —— 这是 Python 的一个比较有个性的地方。附加在 `for` 结尾的 `else` 语句块，_在没有 `break` 发生的情况下会运行_。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "5\n",
      "7\n",
      "11\n",
      "13\n",
      "17\n",
      "19\n",
      "23\n",
      "29\n",
      "31\n",
      "37\n",
      "41\n",
      "43\n",
      "47\n",
      "53\n",
      "59\n",
      "61\n",
      "67\n",
      "71\n",
      "73\n",
      "79\n",
      "83\n",
      "89\n",
      "97\n"
     ]
    }
   ],
   "source": [
    "for n in range(2, 100):\n",
    "    if n == 2:\n",
    "        print(n)\n",
    "        continue\n",
    "    for i in range(2, n):\n",
    "        if (n % i) == 0:\n",
    "            break\n",
    "    else:               # 下一行的 print(n) 事实上属于语句块 for i in range(2, n):\n",
    "        print(n)        # 整个循环结束，都没有发生 break 的情况下，才执行一次 print(n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "试比较以下两段代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for n in range(2, 100):\n",
    "    if n == 2:\n",
    "        print(n)\n",
    "        continue\n",
    "    for i in range(2, n):\n",
    "        if (n % i) == 0:\n",
    "            break\n",
    "    print(n)            # 事实上相当于针对 range(2, 100) 中每个 n 都执行了一次 print(n)\n",
    "                        # 这个 print(n) 属于语句块 for n in range(2, 100): "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "5\n",
      "5\n",
      "5\n",
      "7\n",
      "7\n",
      "7\n",
      "7\n",
      "7\n",
      "9\n",
      "11\n",
      "11\n",
      "11\n",
      "11\n",
      "11\n",
      "11\n",
      "11\n",
      "11\n",
      "11\n",
      "13\n",
      "13\n",
      "13\n",
      "13\n",
      "13\n",
      "13\n",
      "13\n",
      "13\n",
      "13\n",
      "13\n",
      "13\n",
      "15\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "17\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "19\n",
      "21\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "23\n",
      "25\n",
      "25\n",
      "25\n",
      "27\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "29\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "31\n",
      "33\n",
      "35\n",
      "35\n",
      "35\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "37\n",
      "39\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "41\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "43\n",
      "45\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "47\n",
      "49\n",
      "49\n",
      "49\n",
      "49\n",
      "49\n",
      "51\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "53\n",
      "55\n",
      "55\n",
      "55\n",
      "57\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "59\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "61\n",
      "63\n",
      "65\n",
      "65\n",
      "65\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "67\n",
      "69\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "75\n",
      "77\n",
      "77\n",
      "77\n",
      "77\n",
      "77\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "81\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "83\n",
      "85\n",
      "85\n",
      "85\n",
      "87\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "89\n",
      "91\n",
      "91\n",
      "91\n",
      "91\n",
      "91\n",
      "93\n",
      "95\n",
      "95\n",
      "95\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "97\n",
      "99\n"
     ]
    }
   ],
   "source": [
    "for n in range(2, 100):\n",
    "    if n == 2:\n",
    "        print(n)\n",
    "        continue\n",
    "    for i in range(2, n):\n",
    "        if (n % i) == 0:\n",
    "            break\n",
    "        print(n)            # 事实上相当于针对 range(2, n) 中每个 i 都执行了一次 print(n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`pass` 语句什么都不干：\n",
    "\n",
    "再比如，\n",
    "```python\n",
    "def someFunction():\n",
    "    pass\n",
    "```\n",
    "\n",
    "又或者：\n",
    "\n",
    "```python\n",
    "for i in range(100):\n",
    "    pass\n",
    "    if i % 2 == 0:\n",
    "        pass\n",
    "```\n",
    "\n",
    "换个角度去理解的话可能更清楚：`pass` 这个语句更多是给写程序的人用的。当你写程序的时候，你可以用 `pass` 占位，而后先写别的部分，过后再回来补充本来应该写在 `pass` 所在位置的那一段代码。\n",
    "\n",
    "写嵌套的判断语句或循环语句的时候，最常用 `pass`，因为写嵌套挺费脑子的，一不小心就弄乱了。所以，经常需要先用 `pass` 占位，而后逐一突破。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## while 循环"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "今天，在绝大多数编程语言中，都提供两种循环结构：\n",
    "\n",
    "> * Collection-controlled loops（以集合为基础的循环）\n",
    "> * Condition-controlled loops（以条件为基础的循环）\n",
    "\n",
    "之前的 `for ... in ...` 就是 Collection-controlled loops；而在 Python 中提供的 Condition-controlled loops 是 `while` 循环。\n",
    "\n",
    "`while` 循环的格式如下：\n",
    "\n",
    "```python\n",
    "while expression:\n",
    "    statements\n",
    "```\n",
    "\n",
    "输出 1000 以内的斐波那契数列的程序如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 \n"
     ]
    }
   ],
   "source": [
    "n = 1000\n",
    "a, b = 0, 1\n",
    "while a < n:\n",
    "    print(a, end=' ')\n",
    "    a, b = b, a+b\n",
    "print()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`for` 和 `while` 的区别在哪里？什么时候应该用哪个？\n",
    "\n",
    "`for` 更适合处理序列类型的数据（Sequence Type）的迭代，比如处理字符串中的每一个字符，比如把 `range()` 返回的数列当作某种序列类型的索引。\n",
    "\n",
    "`while` 更为灵活，因为它后面只需要接上一个逻辑表达式即可。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 一个投骰子赌大小的游戏"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "虽然还不可能随心所欲写程序，但是，你现在具备了起码的 “阅读能力”。有了以上大概的介绍，你也许可以读懂一些代码了 —— 它们在你眼里再也不是天书了……\n",
    "\n",
    "以下是一个让用户和程序玩掷骰子赌大小的程序。规则如下：\n",
    "\n",
    ">* 每次计算机随机生成一个 `2... 12` 之间的整数，用来模拟机器人投两个骰子的情况；\n",
    "* 机器人和用户的起始资金都是 10 个硬币\n",
    "* 要求用户猜大小：\n",
    "    * 用户输入 `b` 代表 “大”；\n",
    "    * 用户输入 `s` 代表 “小”；\n",
    "    * 用户输入 `q` 代表 “退出”；\n",
    "* 用户的输入和随机产生的数字比较有以下几种情况：\n",
    "    * 随机数小于 `7`，用户猜小，用户赢；\n",
    "    * 随机数小于 `7`，用户猜大，用户输；\n",
    "    * 随机数等于 `7`，用户无论猜大还是猜小，结局平，不输不赢；\n",
    "    * 随机数大于 `7`，用户猜小，用户输；\n",
    "    * 随机数大于 `7`，用户猜大，用户赢；\n",
    "* 游戏结束条件：\n",
    "    * 机器人和用户，若任意一方硬币数量为 `0`，则游戏结束；\n",
    "    * 用户输入了 `q` 主动终止游戏。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from random import randrange\n",
    "\n",
    "coin_user, coin_bot = 10, 10 # 可以用一个赋值符号分别为多个变量赋值\n",
    "rounds_of_game = 0\n",
    "\n",
    "def bet(dice, wager):    # 接收两个参数，一个是骰子点数，另一个用户的输入\n",
    "    if dice == 7:\n",
    "        print(f'The dice is {dice};\\nDRAW!\\n') # \\n 是换行符号\n",
    "        return 0\n",
    "    elif dice < 7:\n",
    "        if wager == 's':\n",
    "            print(f'The dice is {dice};\\nYou WIN!\\n')\n",
    "            return 1\n",
    "        else:\n",
    "            print(f'The dice is {dice};\\nYou LOST!\\n')\n",
    "            return -1\n",
    "    elif dice > 7:\n",
    "        if wager == 's':\n",
    "            print(f'The dice is {dice};\\nYou LOST!\\n')\n",
    "            return -1\n",
    "        else:\n",
    "            print(f'The dice is {dice};\\nYou WIN!\\n')\n",
    "            return 1\n",
    "\n",
    "while True:         #  除 for 之外的另外一个循环语句\n",
    "    print(f'You: {coin_user}\\t Bot: {coin_bot}')\n",
    "    dice = randrange(2, 13)   # 生成一个 2 到 12 的随机数\n",
    "    wager = input(\"What's your bet? \")\n",
    "    if wager == 'q':\n",
    "        break \n",
    "    elif wager in 'bs':  # 只有当用户输入的是 b 或者 s 得时候，才 “掷骰子”……\n",
    "        result = bet(dice, wager)\n",
    "        coin_user += result    # coin_user += result 相当于 coin_user = coin_user + result\n",
    "        coin_bot -= result\n",
    "        rounds_of_game += 1\n",
    "    if coin_user == 0:\n",
    "        print(\"Woops, you've LOST ALL, and game over!\")\n",
    "        break\n",
    "    elif coin_bot == 0:\n",
    "        print(\"Woops, the robot's LOST ALL, and game over!\")\n",
    "        break\n",
    "   \n",
    "print(f\"You've played {rounds_of_game} rounds.\\n\")\n",
    "print(f\"You have {coin_user} coins now.\\nBye!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有控制流，才能算得上是程序。\n",
    "\n",
    "> * 只处理一种情况，用 `if ... `\n",
    "> * 处理 `True`/`False` 两种情况，用 `if ... else ...`\n",
    "> * 处理多种情况，用 `if ... elif ... elif ... else ...`\n",
    "> * 迭代有序数据类型，用 `for ... in ...`，如果需要处理没有 `break` 发生的情况，用 `for ... else ...`\n",
    "> * 其它循环，用 `while ...`\n",
    "> * 与循环相关的语句还有 `continue`、`break`、`pass`\n",
    "> * 函数从控制流角度去看其实就是子程序"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
